<template>
  <el-dialog v-model="visible" :title="!dataForm.id ? '新增' : '修改'" :close-on-click-modal="false" :width="1280">
    <el-form class="dialog-content" ref="dataFormRef" :model="dataForm" :rules="dataRules" label-width="100px">
      <el-form-item label="题目标题" prop="title">
        <el-input v-model="dataForm.title" placeholder="请输入题目标题" />
      </el-form-item>
      <el-form-item label="题目内容" prop="content">
        <div style="border: 1px solid #dcdfe6; border-radius: 4px;">
          <Toolbar
            style="border-bottom: 1px solid #ccc"
            :editor="contentEditorRef"
            :defaultConfig="toolbarConfig"
            :mode="'simple'"
          />
          <Editor
            style="height: 320px; overflow-y: hidden;"
            v-model="dataForm.content"
            :defaultConfig="editorConfig"
            :mode="'simple'"
            @onCreated="handleContentCreated"
          />
        </div>
      </el-form-item>
      <el-form-item label="题目答案" prop="answer">
        <div style="border: 1px solid #dcdfe6; border-radius: 4px;">
          <Toolbar
            style="border-bottom: 1px solid #ccc"
            :editor="answerEditorRef"
            :defaultConfig="toolbarConfig"
            :mode="'simple'"
          />
          <Editor
            style="height: 320px; overflow-y: hidden;"
            v-model="dataForm.answer"
            :defaultConfig="editorConfig"
            :mode="'simple'"
            @onCreated="handleAnswerCreated"
          />
        </div>
      </el-form-item>
      <el-form-item label="题目难度" prop="difficulty">
        <el-select v-model="dataForm.difficulty" placeholder="请选择题目难度" >
          <el-option 
            v-for="item in props.difficultyMap" 
            :key="item[0]" 
            :label="item[1]" 
            :value="Number(item[0])" 
          />
        </el-select>
      </el-form-item>
      <el-form-item label="题目分类" prop="questionCategoryId">
        <el-select 
        v-model="dataForm.questionCategoryId" 
        placeholder="请选择题目分类"
        v-loading="categoryState.dataListLoading"
        :data="categoryState.dataList"
        filterable
        >
          <el-option v-for="category in categoryState.dataList" :label="category.name" :value="category.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="题目标签" prop="tagIdList">
        <el-cascader
        placeholder="请选择题目标签"
        clearable
        filterable
        style="width: 100%;"
        :show-all-levels="false"
        :props="tagProps"
        :options="tagData"
        v-model="dataForm.tagIdList"
        @change="tagChangeHandle"
        />
      </el-form-item>
      <el-form-item label="题目状态" prop="status">
        <el-select v-model="dataForm.status" placeholder="请选择题目状态" >
          <el-option 
            v-for="item in props.statusMap" 
            :key="item[0]" 
            :label="item[1]" 
            :value="`${item[0]}`" 
          />
        </el-select>
      </el-form-item>
      <el-form-item label="VIP专属" prop="isVip">
        <el-select v-model="dataForm.isVip" placeholder="请选择是否为VIP专属" >
          <el-option 
            v-for="item in props.vipMap" 
            :key="item[0]" 
            :label="item[1]" 
            :value="Number(item[0])" 
          />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="submitHandle()">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { nextTick, reactive, ref, inject, onBeforeUnmount, shallowRef, onMounted } from 'vue'
import { useCrud } from '@/hooks/useCrud'
import { ListVO,TagSearchDTO, TagListVO, CategorySearchDTO, CategoryListVO } from '../data'
import { FormRules, type FormInstance } from 'element-plus'
import { add, update } from '../service'
import { IHooksOptions } from '@/hooks/useCrud/data.d'
import { ElMessage } from 'element-plus';
import { Http } from '@/network/request'

// 引入wangEditor
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'

// 为内容和答案分别创建编辑器实例
const contentEditorRef = shallowRef()
const answerEditorRef = shallowRef()

// 处理内容编辑器创建
const handleContentCreated = (editor: any) => {
  contentEditorRef.value = editor
}

// 处理答案编辑器创建
const handleAnswerCreated = (editor: any) => {
  answerEditorRef.value = editor
}

const toolbarConfig: Partial<IToolbarConfig> = {
  insertKeys:{
    index: 23,
    keys: ['uploadVideo'],
  }
}
type InsertFnType = (data: string) => void
const editorConfig: Partial<IEditorConfig> = {
  // 初始化 MENU_CONF 属性
  MENU_CONF: {
    uploadImage: {
      fieldName: 'file', // 上传图片的字段名
      maxNumberOfFiles: 10, // 最多可上传几个文件，默认为 100
      base64LimitSize: 5 * 1024, // 小于5kb就插入 base64 格式（而不上传）
      allowedFileTypes: ['image/*'], //文件类型限制
      async customUpload(file: File, insertFn: InsertFnType) {
        const formData = new FormData()
        formData.append('file', file)  // 确保使用正确字段名
        
        try {
          const res = await Http.post('/file/upload', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'  // 必须设置请求头
            }
          })
          
          if (res.code === 0 && res.data) {
            insertFn(res.data as string)  // 根据实际返回结构调整
          }
        } catch (error) {
          ElMessage.error('图片上传失败')
        }
      }
    },
    uploadVideo:{
      fieldName: 'file', // 上传视频的字段名
      maxFileSize: 5 * 1024 * 1024, //单个文件的最大体积限制5M
      maxNumberOfFiles: 5, //最多可上传几个文件
      allowedFileTypes: ['video/*'], //文件类型限制
      async customUpload(file: File, insertFn: InsertFnType) {
        const formData = new FormData()
        formData.append('file', file)  // 确保使用正确字段名
        
        try {
          const res = await Http.post('/file/upload', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'  // 必须设置请求头
            }
          })
          
          if (res.code === 0 && res.data) {
            insertFn(res.data as string)  // 根据实际返回结构调整

          }
        } catch (error) {
          ElMessage.error('视频上传失败')
        }
      }
    }
  },
}

// 组件销毁时，销毁两个编辑器实例
onBeforeUnmount(() => {
  const contentEditor = contentEditorRef.value
  const answerEditor = answerEditorRef.value
  if (contentEditor) contentEditor.destroy()
  if (answerEditor) answerEditor.destroy()
})

// 接收父组件传递的题目标签数据
const tagData = inject('tagData')
// 处理标签选择变化
const tagChangeHandle = (value: string[][]) => {
  if (value.length > 10) {
    // 若选择数量超过 10 个，截取前 10 个
    const limitedValue = value.slice(0, 10);
    const secondLevelTags = limitedValue.map(item => item[1]).filter(Boolean);
    dataForm.tagIdList = secondLevelTags;
    ElMessage.warning('最多只能选择 10 个标签');
  } else {
    // 只保留二级标签的值
    const secondLevelTags = value.map(item => item[1]).filter(Boolean);
    dataForm.tagIdList = secondLevelTags;
  }
};

const emit = defineEmits<{
  (e: 'refreshDataList'): void
}>()

const visible = ref(false)
const dataFormRef = ref<FormInstance>()

const dataForm = reactive<ListVO>({
  id: '',
  title: '',
  content: '',
  answer: '',
  difficulty: null,
  questionCategoryId: '',
  status: null,
  isVip: null,
  tagIdList: [],
})

const init = async (row?: ListVO) => {
  visible.value = true
  await nextTick()
  dataForm.id = ''

  // 重置表单数据
  if (dataFormRef.value) {
    dataFormRef.value.resetFields()
  }

  if (row) {
    Object.assign(dataForm, row)
  }
}

const dataRules = reactive<FormRules<ListVO>>({
  title: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  answer: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  difficulty: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  questionCategoryId: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  tagIdList: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  status: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
  isVip: [{ required: true, message: '必填项不能为空', trigger: 'blur' }],
})

// 表单提交
const submitHandle = () => {
  dataFormRef.value!.validate(async (valid) => {
    if (!valid) return

    const res = dataForm.id ? await update(dataForm) : await add(dataForm)
    if (res) {
      visible.value = false
      emit('refreshDataList')
    }
  })
}

// 获取题目标签列表
const tagState: IHooksOptions<TagSearchDTO, TagListVO> = reactive({
  dataListUrl: '/codeDuckTag/list',
  isPage: false,
  queryForm:{
    name: '',
  }
})

const {getDataList: getTagDataList } = useCrud<TagSearchDTO,TagListVO>(tagState)

// 获取题目分类列表
const categoryState: IHooksOptions<CategorySearchDTO,CategoryListVO> = reactive({
  dataListUrl: '/admin/codeDuckQuestionCategory/listQuestionCategory',
  queryForm:{
    name: '',
  }
})

const { getDataList: getCategoryDataList } = useCrud<CategorySearchDTO,CategoryListVO>(categoryState)

const tagProps = {
  value: "id",
  label: "name",
  children: "children",
  multiple: true,
}

// 定义暴露的方法
defineExpose({
  init,
})

// 定义接收的 props
const props = defineProps<{
  difficultyMap: Map<string, string>
  statusMap: Map<string, string>
  vipMap: Map<string, string>
}>()
</script>
<style scope lang="scss">
// 修复全屏层级问题
.w-e-full-screen-container {
  z-index: 9999 !important; // 必须高于el-dialog的z-index(默认2000)
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
}
// 修改级联选择器的高度
.el-cascader-panel {
    height: 40vh;
    .el-scrollbar__wrap {
      height: 100%;
    }
  }
.dialog-content {
  max-height: 65vh; // 设置最大高度为视口高度的 80%
  overflow-y: auto; // 当内容超出最大高度时，显示垂直滚动条
}
</style>
